package com.fintech.pangu.oauth2.config.token;

import com.fintech.pangu.oauth2.properties.OAuth2AuthorizationServerProperties;
import com.fintech.pangu.oauth2.properties.token.TokenStoreType;
import com.fintech.pangu.oauth2.token.ReadWriteCompositeTokenStore;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.oauth2.provider.token.TokenStore;

import java.util.ArrayList;
import java.util.List;


/**
 * Token存储配置
 */
@Configuration
@Import({ DBTokenStoreConfig.class, RedisTokenStoreConfig.class })  // 导入相关Token存储配置
public class TokenStoreConfig {

    @Autowired
    private OAuth2AuthorizationServerProperties oAuth2AuthorizationServerProperties;

    @Autowired(required = false)
    private TokenStore jdbcTokenStore;

    @Autowired(required = false)
    private TokenStore redisTokenStore;


    /**
     * 构造读写分离的TokenStore
     * @return
     */
    @ConditionalOnProperty(prefix = "pangu.security.oauth2.server.tokenStore", name = "enableReadWriteCompositeTokenStore", havingValue = "true", matchIfMissing = true)
    @Bean
    public TokenStore readWriteCompositeTokenStore(){
        // 配置信息
        String[] readTypes = oAuth2AuthorizationServerProperties.getTokenStore().getReadTokenStoreType();
        String[] writeTypes = oAuth2AuthorizationServerProperties.getTokenStore().getWriteTokenStoreType();

        // 读写TokenStore
        List<TokenStore> readTokenStores = new ArrayList<>();
        List<TokenStore> writeTokenStores = new ArrayList<>();

        // 读
        if(ArrayUtils.isNotEmpty(readTypes)){
            for(String readType : readTypes){
                readTokenStores.add(getTokenStoreFromType(readType));
            }
        }

        // 写
        if(ArrayUtils.isNotEmpty(writeTypes)){
            // TODO 顺序，事务
            for(String writeType : writeTypes){
                writeTokenStores.add(getTokenStoreFromType(writeType));
            }
        }

        return new ReadWriteCompositeTokenStore(readTokenStores, writeTokenStores);
    }


    /**
     * 根据类型获取TokenStore
     * @param type
     * @return
     */
    private TokenStore getTokenStoreFromType(String type){
        switch (type.toLowerCase()) {
            case TokenStoreType.db:
                return jdbcTokenStore;
            case TokenStoreType.redis:
                return redisTokenStore;
            default:
                return null;
        }
    }

}
